package com.flydog.taskManager.entity;

import com.fasterxml.jackson.annotation.JsonValue;
import com.flydog.taskManager.common.converter.ProcessStatusConverter;
import com.flydog.taskManager.common.converter.RepeatModeConverter;
import com.flydog.taskManager.dto.ProcessStatus;
import com.flydog.taskManager.dto.RepeatMode;
import com.flydog.taskManager.repository.PeriodicTaskEndTimeRepository;
import lombok.Getter;
import lombok.RequiredArgsConstructor;
import lombok.Setter;
import lombok.ToString;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.annotation.Transient;

import javax.persistence.*;
import java.util.Calendar;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

/**
 * @author Cao
 * @description 周期性工作实体
 * @create 2021-05-08
 */
@Table(name = "PERIODIC_TASK")
@Entity
@Getter
@Setter
@ToString
@RequiredArgsConstructor
public class PeriodicTask extends Task {

    @Convert(converter = RepeatModeConverter.class)
    @Enumerated
    @Column(name = "repeat_mode", nullable = false)
    private RepeatMode repeatMode;

    @Column(name = "repeat_num", nullable = false)
    private Integer repeatNum;

    @Column(name = "period_end_time")
    private Calendar periodEndTime;

    /**
     * 上一周期完成状态。
     * 0 '未完成'
     * 1 "已完成"
     */
    @Convert(converter = ProcessStatusConverter.class)
    @Enumerated
    @Column(name = "prev_status")
    private ProcessStatus prevStatus;

    /**
     * 本周期完成状态。
     * 0 '未完成'
     * 1 "已完成"
     */
    @Convert(converter = ProcessStatusConverter.class)
    @Enumerated
    @Column(name = "curr_status")
    private ProcessStatus currStatus;

    /**
     * 根据时间刷新工作状态。包括：设置周期结束时间，设置上周期完成状态，设置本周期工作状态
     *
     * @param refreshTime 刷新时间
     */
    public void refreshTaskStatus(Calendar refreshTime) {
        Calendar preSetEndTime = getPreSetPeriodEndTime(refreshTime);
        if (refreshTime.before(super.getEnd())) {
            if (periodEndTime.before(refreshTime)) {
                prevStatus = currStatus == ProcessStatus.DONE ? ProcessStatus.DONE : ProcessStatus.UNDONE;
                currStatus = ProcessStatus.PROCESSING;
            }
            periodEndTime = preSetEndTime;
        } else {
            super.setProcessStatus(ProcessStatus.DONE);
            prevStatus = currStatus == ProcessStatus.DONE ? ProcessStatus.DONE : ProcessStatus.UNDONE;
            currStatus = ProcessStatus.DONE;
            periodEndTime = super.getEnd();
        }
    }

    public void initTaskStatus(Calendar initTime) {
        Calendar preSetEndTime = getPreSetPeriodEndTime(initTime);
        if (initTime.before(super.getEnd())) {
            periodEndTime = preSetEndTime;
            prevStatus = null;
            currStatus = ProcessStatus.PROCESSING;
            super.setProcessStatus(ProcessStatus.PROCESSING);
        } else {
            super.setProcessStatus(ProcessStatus.DONE);
            prevStatus = currStatus == ProcessStatus.DONE ? ProcessStatus.DONE : ProcessStatus.UNDONE;
            currStatus = ProcessStatus.DONE;
        }
    }

    private Calendar getPreSetPeriodEndTime(Calendar setTime) {
        Calendar preSetEndTime = repeatMode.getPeriodEndTime(setTime, repeatNum);
        if (super.getEnd().before(preSetEndTime)) {
            preSetEndTime = super.getEnd();
        }
        return preSetEndTime;
    }

}